ποΈGitΠ―ΡΠ°ποΈ
Node / meshtastic / Meshtastic-Android / files / specs / 20260507-161858-app-docs-markdown / tasks.md
specs/20260507-161858-app-docs-markdown/tasks.md bc4e9da3ad7a2a22768cbaecc75810e018bc40e2 (bc4e9da3) Text, 38.85 KB
description: "Task list for feature: App Documentation (Android/KMP)"
Tasks: App Documentation (Android/KMP)
Input: Design documents from T383838specs/003-app-docs-markdown/
Prerequisites: T383838spec.md, T383838plan.md, T383838research.md, T383838data-model.md, T383838contracts/, T383838quickstart.md
Status: Complete (Phases 0β14)
Format: T383838[ID] [P?] [Story] Description
β’ [P]: Can be worked in parallel if dependencies are satisfied
β’ [Story]: T383838US1..T383838US5 map to the user stories in T383838spec.md
β’ Every task names the primary file paths to touch
Phase 0: Design Standards Gate (Blocking)
Purpose: Review Meshtastic design standards before shipping any new UI for docs or the Chirpy assistant.
β’ [X] T000 [UI-GATE] Review T383838.skills/design-standards/SKILL.md and upstream Meshtastic design standards; record constraints for T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/DocsBrowserScreen.kt, T383838ChirpyAssistantSheet.kt, and screenshot styling.
β’ [X] T001 [UI-GATE] Confirm icon choices in T383838core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/icon/ for help/search/info/security states and choose MeshtasticIcons equivalents for docs UI and reference tables.
Checkpoint: Design constraints are documented and ready to guide implementation.
Phase 1: Documentation Content
Purpose: Author the docs corpus that both the website and in-app browser will consume.
User Guide pages
β’ [X] T010 [P] [US1] Create T383838docs/user/onboarding.md covering first launch, intro flow, permissions, and initial setup using content from T383838feature/intro/src/androidMain/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt, T383838LocationScreen.kt, and T383838NotificationsScreen.kt.
β’ [X] T011 [P] [US1] Create T383838docs/user/connections.md covering Bluetooth, USB, and TCP connection flows using T383838feature/intro/.../BluetoothScreen.kt and T383838feature/connections/** as authoritative sources.
β’ [X] T012 [P] [US1] Create T383838docs/user/messages-and-channels.md covering conversations, channel security, direct messages, and message state using T383838feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/Message.kt and T383838component/MessageScreenComponents.kt.
β’ [X] T013 [P] [US1] Create T383838docs/user/nodes.md covering node list status, roles, badges, and quick actions using T383838feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt.
β’ [X] T014 [P] [US1] Create T383838docs/user/node-metrics.md covering node detail, device metrics, environment metrics, signal, power, traceroute, and logs using T383838feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreens.kt and T383838metrics/*.
β’ [X] T015 [P] [US1] Create T383838docs/user/map-and-waypoints.md covering maps, waypoints, and map-specific actions using T383838feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/MapScreen.kt.
β’ [X] T016 [P] [US1] Create T383838docs/user/settings-radio-user.md covering radio, LoRa, display, and user settings using T383838feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/DeviceConfigurationScreen.kt.
β’ [X] T017 [P] [US1] Create T383838docs/user/settings-module-admin.md covering module, administration, and advanced settings using T383838feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/ModuleConfigurationScreen.kt and T383838AdministrationScreen.kt.
β’ [X] T018 [P] [US1] Create T383838docs/user/telemetry-and-sensors.md covering telemetry surfaces and sensor interpretation using T383838feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt, T383838PowerMetrics.kt, and related metric screens.
β’ [X] T019 [P] [US1] Create T383838docs/user/tak.md covering TAK integration and setup using T383838feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/TAKConfigItemList.kt and related settings screens.
β’ [X] T020 [P] [US1] Create T383838docs/user/mqtt.md covering MQTT setup and usage using T383838feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt and messaging references.
β’ [X] T021 [P] [US1] Create T383838docs/user/discovery.md covering local mesh discovery and node exploration based on current discovery-related UI/state and app navigation flows. Note: Feature 001 (Local Mesh Discovery) is Not Started β author this page as a concept/goals overview initially and revise with screenshots and detailed UI guidance once 001 reaches Phase 5+ UI milestones.
β’ [X] T022 [P] [US1] Create T383838docs/user/firmware.md covering update flows, warnings, and recovery using T383838feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt.
β’ [X] T023 [P] [US1] Create T383838docs/user/desktop.md covering Desktop host usage, transport differences, and parity notes using T383838desktop/src/main/kotlin/org/meshtastic/desktop/ and shared navigation patterns.
Developer Guide pages
β’ [X] T024 [P] [US4] Create T383838docs/developer/architecture.md describing layer boundaries (T383838app, T383838desktop, T383838feature/*, T383838core/*) and shared KMP responsibilities.
β’ [X] T025 [P] [US4] Create T383838docs/developer/codebase.md documenting repository layout, namespacing, and build-logic conventions.
β’ [X] T026 [P] [US4] Create T383838docs/developer/adding-a-feature-module.md documenting T383838meshtastic.kmp.feature, source sets, DI, resources, and testing expectations.
β’ [X] T027 [P] [US4] Create T383838docs/developer/navigation-and-deep-links.md documenting T383838Routes.kt, T383838DeepLinkRouter.kt, and Navigation 3 graph registration patterns.
β’ [X] T028 [P] [US4] Create T383838docs/developer/transport.md documenting BLE, TCP, Serial/USB, and host-specific abstractions.
β’ [X] T029 [P] [US4] Create T383838docs/developer/persistence.md documenting Room KMP, DataStore/core:prefs, and where docs intentionally do not use persistence.
β’ [X] T030 [P] [US4] Create T383838docs/developer/testing.md documenting KMP test strategy, host tests, and planned screenshot automation.
β’ [X] T031 [P] [US4] Create T383838docs/developer/contributing.md documenting branch naming, verification, and PR hygiene.
Content-supporting assets
β’ [X] T032 [P] [US1] Create or inventory T383838docs/assets/screenshots/ references and map each page to required PNG or SVG assets.
β’ [X] T033 [P] [US1] Extract onboarding tips, warnings, and disclaimers from T383838feature/intro/**, T383838feature/firmware/**, and relevant feature UIs into highlighted callout sections inside the authored markdown.
β’ [X] T034 [US1] Review all markdown for reference-table compliance where 2+ icon/state captures appear together.
Checkpoint: Complete markdown corpus exists with planned screenshots and callouts.
Phase 2: Jekyll Site Setup
Purpose: Make the authored markdown browsable on the web with versioning.
β’ [X] T040 [P] [US1] Create T383838docs/_config.yml with T383838just-the-docs, sidebar search, and the required collection/navigation settings.
β’ [X] T041 [P] [US1] Create T383838docs/index.md redirect behavior for T383838/latest/ and beta handling.
β’ [X] T042 [P] [US1] Create T383838docs/_data/versions.yml with an initial T383838beta entry and stable release entry schema.
β’ [X] T043 [P] [US1] Create any shared include/layout files needed for version selector, beta banner, and consistent screenshot styling.
β’ [X] T044 [US1] Validate local Jekyll build output from the authored markdown and confirm the navigation hierarchy matches the spec.
Checkpoint: Local website build is navigable and version-ready.
Phase 3: Build Pipeline (Markdown β HTML, Index, Bundle)
Purpose: Implement Gradle-native docs generation suitable for KMP.
β’ [X] T050 [P] [US1] Create T383838feature/docs/build.gradle.kts using T383838meshtastic.kmp.feature and dependencies for T383838core:common, T383838core:navigation, T383838core:resources, T383838core:ui, T383838core:di, and existing markdown renderer libraries.
β’ [X] T051 [P] [US1] Add T383838:feature:docs to T383838settings.gradle.kts.
β’ [X] T052 [P] [US1] Add docs-generation support in T383838build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/DocsTasks.kt (or equivalent) with lazy task registration.
β’ [X] T053 [P] [US1] Implement frontmatter parsing, nav-order extraction, and markdown normalization in build logic or T383838feature/docs build task code.
β’ [X] T054 [P] [US1] Implement HTML rendering via T383838flexmark-java (or T383838commonmark-java fallback) in the docs generation task.
β’ [X] T055 [P] [US1] Implement callout and banner post-processing, shared CSS injection, and T383838data-page emission for generated HTML.
β’ [X] T056 [P] [US1] Generate T383838index.json matching T383838specs/003-app-docs-markdown/contracts/keyword-index-schema.json.
β’ [X] T057 [P] [US1] Wire generated output into T383838feature/docs/build/generated/docs/common/ as a Gradle resource source directory.
β’ [X] T058 [P] [US1] Add Android asset mirroring if required for WebView file loading under T383838feature/docs/build/generated/docs/androidAssets/.
β’ [X] T059 [P] [US1] Enforce bundle-size warnings/failures and missing-asset validation in T383838validateDocsBundle.
β’ [X] T060 [US1] Add aggregate root tasks (T383838generateDocsBundle, T383838validateDocsBundle, T383838publishDocsSite) and document their usage.
β’ [X] T061 [P] [US1] [FR-038] Update T383838syncDocsToComposeResources in T383838feature/docs/build.gradle.kts to include T383838assets/screenshots/**/*.png alongside markdown files, and add a task dependency on T383838:screenshot-tests:copyDocsScreenshots to ensure generated screenshots are populated before sync.
β’ [X] T062 [P] [US1] [FR-038] Rewrite or restructure markdown image paths during sync so T383838assets/screenshots/ references resolve to the compose resource file structure expected by the custom T383838ImageTransformer at runtime.
Checkpoint: Gradle can generate the docs bundle and website artifact from markdown.
Phase 4: In-App Doc Browser
Purpose: Ship the offline docs browser inside Settings.
β’ [X] T070 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/model/DocModels.kt implementing the entities from T383838data-model.md.
β’ [X] T071 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/data/DocBundleLoader.kt to load packaged docs metadata and page content.
β’ [X] T072 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/DocsBrowserScreen.kt with grouped TOC, search entry point, and loading/empty states.
β’ [X] T073 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/DocsPageRouteScreen.kt to route page IDs to renderer surfaces.
β’ [X] T074 [P] [US2] Create Android renderer T383838feature/docs/src/androidMain/kotlin/org/meshtastic/feature/docs/ui/DocHtmlView.android.kt using T383838AndroidView + T383838WebView.
β’ [X] T075 [P] [US2] Create Desktop/iOS page renderers in T383838src/jvmMain and T383838src/iosMain using Compose markdown or embedded browser abstraction.
β’ [X] T076 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/navigation/DocsNavigation.kt with typed navigation entries.
β’ [X] T077 [P] [US2] Add T383838SettingsRoute.HelpDocs and T383838SettingsRoute.HelpDocPage to T383838core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt.
β’ [X] T078 [P] [US2] Update T383838core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt for T383838help-docs (canonical) / T383838helpDocs (compat alias) routing.
β’ [X] T079 [P] [US2] Update T383838feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt to add the Help & Documentation row and register docs destinations.
β’ [X] T080 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/di/FeatureDocsModule.kt.
β’ [X] T081 [P] [US2] Include T383838FeatureDocsModule in T383838app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt and T383838desktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt.
β’ [X] T082 [US2] Add shared/unit tests for bundle loading, page ordering, and route serialization under T383838feature/docs/src/commonTest/kotlin/org/meshtastic/feature/docs/.
β’ [X] T083 [P] [US2] [FR-038] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/ComposeResourceImageTransformer.kt implementing T383838ImageTransformer from mikepenz markdown renderer. Must use T383838Res.getUri("files/docs/$link") (synchronous) to resolve local resource URIs, then T383838rememberAsyncImagePainter() from Coil 3 to load the image composably. Must return T383838null for external T383838http:///T383838https:// URLs. Add T383838libs.coil dependency to T383838feature/docs/build.gradle.kts commonMain.
β’ [X] T084 [P] [US2] [FR-038] Update T383838DocsPageRouteScreen.kt to pass T383838ComposeResourceImageTransformer() as the T383838imageTransformer parameter to the T383838Markdown() composable instead of using the default T383838NoOpImageTransformerImpl.
β’ [X] T085 [US2] [FR-038] Verify inline screenshot rendering end-to-end: run T383838copyDocsScreenshots, T383838syncDocsToComposeResources, then launch the docs browser on Desktop and confirm images render inline on a page with T383838! LINK0 references.
Checkpoint: Help & Documentation opens inside Settings and reads bundled content offline.
Phase 5: Search / Index / Discoverability
Purpose: Make the docs corpus searchable on all targets.
β’ [X] T090 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/data/KeywordSearchEngine.kt using T383838KeywordIndexEntry.
β’ [X] T091 [P] [US2] Add alias normalization and title-first ranking logic.
β’ [X] T092 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/DocsSearchBar.kt and wire it into T383838DocsBrowserScreen.kt.
β’ [X] T093 [P] [US2] Add section-aware search results and page suggestions for missing page/deep-link cases.
β’ [X] T094 [P] [US2] Add tests for ranking, aliases, and tie-breaking in T383838KeywordSearchEngineTest.kt.
β’ [X] T095 [US2] Ensure keyword search is the user-visible fallback on unsupported AI targets.
Checkpoint: Search works without AI on every target.
Phase 6: AI Assistant (Gemini Nano)
Purpose: Add an Android-only on-device assistant without breaking KMP or T383838fdroid.
β’ [X] T100 [P] [US3] Create shared AI contracts in T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ai/AIDocAssistant.kt and result/state models.
β’ [X] T101 [P] [US3] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/ChirpyAssistantSheet.kt with chat UI, pinned input, session history, and source-page chips.
β’ [X] T102 [P] [US3] Add keyword-retrieval + token-budget helper logic in shared code.
β’ [X] T103 [P] [US3] Implement Google-flavor Android binding under T383838app/src/google/kotlin/org/meshtastic/app/docs/GoogleDocsAiModule.kt (or equivalent) to call Gemini Nano via Google AI Edge SDK.
β’ [X] T104 [P] [US3] Bind a no-op or keyword-only fallback implementation in T383838app/src/fdroid/kotlin/org/meshtastic/app/di/FlavorModule.kt.
β’ [X] T105 [P] [US3] Bind a Desktop fallback implementation from T383838desktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt.
β’ [X] T105b [P] [US3] Bind an iOS fallback implementation (keyword-search-only, sharing the Desktop fallback pattern) in the iOS Koin module or via a shared non-Android default binding.
β’ [X] T106 [P] [US3] Add runtime capability checks for Android API level, flavor, model availability, and busy/quota states.
β’ [X] T107 [P] [US3] Surface assistant fallback states cleanly in the shared UI and hide the input entirely when unsupported.
β’ [X] T108 [P] [US3] Add tests covering token budget trimming, unsupported platform behavior, and fallback search suggestions.
β’ [X] T109 [US3] Verify the Chirpy vector asset is bundled and rendered correctly across targets.
Checkpoint: Supported Android Google builds get Gemini Nano; all other targets fall back gracefully.
Phase 7: CI Automation and GitHub Pages
Purpose: Keep docs current and deployable.
β’ [X] T120 [P] [US5] Create T383838.github/workflows/docs-deploy.yml using T383838ubuntu-24.04, JDK 21, Gradle setup, docs-generation tasks, and Pages deploy steps.
β’ [X] T121 [P] [US5] Create T383838.github/workflows/docs-release.yml for T383838v*.*.* tags, version manifest updates, and T383838/latest/ redirect refresh.
β’ [X] T122 [P] [US5] Create or wire T383838recordDocsScreenshots to the chosen screenshot framework (T383838Roborazzi preferred, T383838Paparazzi acceptable).
β’ [X] T123 [P] [US5] Add screenshot asset diff detection and automated PR creation logic for changed PNGs.
β’ [X] T124 [P] [US5] Add schema validation against T383838specs/003-app-docs-markdown/contracts/keyword-index-schema.json during CI.
β’ [X] T125 [P] [US5] Add bundle-size validation and missing-asset validation to CI as blocking steps.
β’ [X] T126 [P] [US5] Update workflow permissions and Pages artifact publishing configuration.
β’ [X] T127 [US5] Dry-run the workflows locally as far as practical and verify contract alignment.
Checkpoint: Docs build, validate, and deploy automatically in CI.
Phase 8: Polish, Accessibility, and Edge Cases
Purpose: Final quality pass before implementation is considered complete.
β’ [X] T130 [P] [US2] Add accessibility labels, headings, and focus order checks to docs browser and Chirpy UI.
β’ [X] T131 [P] [US2] Validate dark-mode rendering for generated HTML, screenshots, and icon reference tables.
β’ [X] T132 [P] [US2] Handle missing-page and stale-deep-link fallbacks in the docs browser UI.
β’ [X] T133 [P] [US3] Add explicit user messaging for Gemini busy/quota/model-not-installed states.
β’ [X] T134 [P] [US1] Review all pages for plain-language voice, no internal jargon leaks, and consistency with current UI strings.
β’ [X] T135 [P] [US4] Review developer docs for correctness against actual modules, routes, and DI setup.
β’ [X] T136 [P] [US5] Validate Lighthouse accessibility on the generated site and record results.
β’ [X] T137 [P] [US5] Add README updates for Help & Documentation and the deep-link contract.
β’ [X] T138 [US1] Run final verification: T383838./gradlew spotlessCheck detekt kmpSmokeCompile test allTests generateDocsBundle validateDocsBundle publishDocsSite.
Checkpoint: Feature is accessible, correct, and release-ready.
Dependency Notes
β’ Phase 0 blocks all UI work.
β’ Phase 1 (content) and Phase 2 (site scaffolding) can overlap.
β’ Phase 3 must finish before Phase 4 can load generated bundles reliably.
β’ T083/T084 (ImageTransformer) depend on T061/T062 (screenshots must be bundled before the transformer can resolve them).
β’ Phase 5 depends on Phase 3 metadata/index generation and Phase 4 browser UI.
β’ Phase 6 depends on Phase 5 because AI retrieval uses the keyword index and search engine.
β’ Phase 7 depends on Phases 2 and 3.
β’ Phase 8 depends on all preceding phases.
β’ Phase 10 depends on Phases 1β9 (all content and CI must be in place before Docusaurus sync).
β’ Phase 11 depends on Phases 9β10 (governance workflows and sync script must exist before consolidation).
β’ Phase 12 depends on Phase 6 (Chirpy assistant must exist before UX polish).
β’ Phase 13 depends on Phase 12 (Chirpy bubble redesign must exist before further polish).
Recommended Delivery Order
1. Ship US1 first (web docs + pipeline).
2. Add US2 (in-app browser + deep links).
3. Add US3 (Gemini Nano + fallbacks).
4. Finish US4 polishing and architecture docs.
5. Finish US5 automation and screenshot bot flow.
Phase 9: Apple Alignment (Cross-Platform Feature Parity)
Purpose: Close feature gaps identified by comparing with T383838meshtastic-apple docs implementation.
β’ [X] T200 [P] [US1] Create T383838docs/user/signal-meter.md explaining LoRa signal quality, RSSI vs SNR, bar-level criteria, and common misconceptions β adapted from Apple equivalent for Android-specific signal surfaces.
β’ [X] T201 [P] [US1] Create T383838docs/user/units-and-locale.md explaining automatic metric/imperial formatting via T383838MetricFormatter, covering temperature, distance, speed, wind, rainfall, and locale settings β adapted from Apple equivalent for Android/KMP.
β’ [X] T202 [P] [US2] Add T383838iconId: String? field to T383838DocPage and T383838KeywordIndexEntry models in T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/model/DocModels.kt.
β’ [X] T203 [P] [US2] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ui/DocPageIconResolver.kt mapping T383838iconId values to T383838MeshtasticIcons vectors (equivalent to Apple's SF Symbols per-page mapping).
β’ [X] T204 [P] [US2] Update T383838DocsBrowserScreen.kt TOC list items to show leading icon using T383838resolveIcon().
β’ [X] T205 [P] [US2] Update T383838DocBundleLoader.kt static index with T383838iconId for all 24 pages and add two new T383838KeywordIndexEntry entries for T383838signal-meter and T383838units-and-locale.
β’ [X] T206 [P] [US5] Create T383838.github/workflows/docs-staleness.yml β advisory CI workflow that posts a PR comment when user-facing UI files change without corresponding T383838docs/ updates, with T383838skip-docs-check label bypass (adapted from Apple's T383838docs-staleness.yml for Android KMP paths).
Checkpoint: Feature parity with Apple docs: per-page icons in TOC, two new user guide pages, and docs staleness CI check.
Phase 10: Docusaurus Sync & Content Gaps (meshtastic.org Parity)
Purpose: Close gaps identified by comparing with Apple's T383838sync-apple-docs.js workflow (PR meshtastic/meshtastic#2393) and Apple in-app doc content. Ensures Android docs are published on meshtastic.org alongside Apple docs and addresses missing content pages.
Depends on: Phases 1β9 (all content and CI must be in place before sync).
Content
β’ [X] T210 [P] [US1] [FR-041] Create T383838docs/user/translate.md β "Translate the App" contributor guide explaining how to submit translations via Crowdin. Cover: link to Crowdin project, which files are translatable (composeResources T383838strings.xml, T383838docs/user/*.md), step-by-step workflow, and how to add a new locale. Add frontmatter with T383838nav_order: 17. Add Crowdin string resources for title and keywords.
β’ [X] T211 [P] [US4] [FR-042] Create T383838docs/developer/measurement.md β developer guide for the T383838MetricFormatter API and locale-aware unit conversion. Cover: supported measurement types (temperature, distance, speed, wind, rainfall), how locale detection works, how to add a new measurement type, and testing patterns. Reference T383838core/common/src/commonMain/kotlin/org/meshtastic/core/common/util/ formatters.
β’ [X] T212 [P] [US2] Update T383838DocBundleLoader.kt static index with new pages (T383838translate, T383838measurement), T383838iconId mappings, and T383838KeywordIndexEntry entries. Update nav ordering for existing pages to accommodate the two new entries.
Docusaurus Sync Script
β’ [X] T220 [P] [US5] [FR-039] Create T383838scripts/sync-android-docs.js β Node.js script that reads T383838docs/user/*.md and T383838docs/developer/*.md, transforms them for Docusaurus compatibility (rewrite frontmatter to Docusaurus format, fix sibling T383838.md links, rewrite image paths to T383838static/img/android/), and writes output to a staging directory. Model after Apple's T383838scripts/sync-apple-docs.js structure.
β’ [X] T221 [P] [US5] [FR-040] Add T383838--convert-webp flag to T383838sync-android-docs.js that converts PNG/JPG screenshots to WebP via T383838cwebp and rewrites image references in markdown. Original PNGs remain canonical in-repo.
β’ [X] T222 [P] [US5] [FR-039] Create T383838.github/workflows/sync-android-docs.yml β workflow triggered on push to T383838main when T383838docs/** files change. Steps: checkout, install Node.js and T383838webp, run T383838sync-android-docs.js --convert-webp, copy images to T383838static/img/android/, and open a PR in T383838meshtastic/meshtastic targeting T383838docs/software/android/. Use T383838ubuntu-24.04 runner and T383838peter-evans/create-pull-request or equivalent action.
β’ [X] T223 [US5] Dry-run the sync script locally: run T383838node scripts/sync-android-docs.js --convert-webp --dry-run and verify output structure matches Docusaurus expectations (T383838docs/software/android/user/*.md, T383838docs/software/android/developer/*.md, T383838static/img/android/*.webp).
Integration
β’ [X] T230 [P] [US2] Add Crowdin string resources for T383838translate.md title (T383838doc_title_translate) and keywords (T383838doc_keywords_translate) in T383838core/resources/src/commonMain/composeResources/values/strings.xml. Run T383838python3 scripts/sort-strings.py.
β’ [X] T231 [P] [US2] Add Crowdin string resources for T383838measurement.md title (T383838doc_title_measurement) and keywords (T383838doc_keywords_measurement). Run T383838python3 scripts/sort-strings.py.
β’ [X] T232 [US1] Update T383838docs/user.md and T383838docs/developer.md What's New sections to include T383838translate.md and T383838measurement.md. Jekyll scope-based defaults handle nav/sidebar automatically.
β’ [X] T233 [US5] Verified T383838crowdin.yml glob T383838/docs/user/*.md already covers T383838translate.md β no update needed.
β’ [X] T234 [US1] Run final verification: T383838./gradlew spotlessApply detekt :feature:docs:allTests.
Checkpoint: Android docs published on meshtastic.org, translate contributor page live, developer measurement docs complete.
Phase 11: Governance Consolidation & Script Optimization
Purpose: Eliminate duplication across docs governance scripts and CI workflows. Reduce the number of places that must be manually updated when adding a doc page from 3 to 2 (markdown file + DocBundleLoader only).
Depends on: Phases 9β10 (governance workflows and sync script must exist).
Shared Library
β’ [X] T240 [P] [US5] [FR-044] Create T383838scripts/lib/frontmatter.js with T383838parseFrontmatter(), T383838discoverSlugs(), and T383838forEachDocPage() utilities. Consolidates 4 independent frontmatter parsers and directory traversal patterns.
β’ [X] T241 [P] [US5] [FR-044] Refactor T383838scripts/validate-doc-links.js to use shared T383838discoverSlugs() and T383838forEachDocPage().
β’ [X] T242 [P] [US5] [FR-044] Refactor T383838scripts/check-doc-freshness.js to use shared T383838parseFrontmatter() and T383838forEachDocPage().
β’ [X] T243 [P] [US5] [FR-044] Refactor T383838scripts/check-doc-coverage.js to use shared T383838forEachDocPage().
β’ [X] T244 [P] [US5] [FR-044] Refactor T383838scripts/sync-android-docs.js to use shared T383838discoverSlugs() β replace hardcoded T383838KNOWN_USER_SLUGS and T383838KNOWN_DEV_SLUGS sets with filesystem-derived discovery.
Workflow Consolidation
β’ [X] T250 [P] [US5] [FR-045] Merge T383838docs-staleness.yml into T383838docs-governance.yml as a parallel T383838staleness job. The staleness job uses T383838fetch-depth: 0 for git diff; the T383838validate job uses T383838fetch-depth: 1.
β’ [X] T251 [P] [US5] [FR-045] Remove standalone T383838.github/workflows/docs-staleness.yml.
β’ [X] T252 [US5] Remove slug registry validation step from T383838docs-governance.yml (no longer needed since slugs are filesystem-derived).
β’ [X] T253 [US5] Remove duplicate link validation step and Node.js setup from T383838docs-deploy.yml. Remove unused T383838pull-requests: write permission.
3-Consumer Propagation
β’ [X] T260 [P] [US5] [FR-043] Update Constitution principle VI to explicitly name in-app, Jekyll, and Docusaurus consumers with propagation rules.
β’ [X] T261 [US5] Update staleness check PR comment to include new-page checklist for all 3 consumer registries.
β’ [X] T262 [US5] Add T383838DocBundleLoader registry validation step to T383838docs-governance.yml (ensures every doc page is registered in the in-app index).
Cleanup
β’ [X] T270 [US5] Remove duplicate T383838sync-android-docs.js from meshtastic/meshtastic PR #2405 (workflow runs from Android clone).
β’ [X] T271 [US5] Update T383838docs/developer.md references from T383838docs-staleness to consolidated T383838Docs Governance workflow.
β’ [X] T272 [US5] Verify all 4 scripts pass locally: T383838validate-doc-links, T383838check-doc-freshness, T383838check-doc-coverage, T383838sync-android-docs --dry-run.
Checkpoint: Single docs governance workflow, shared frontmatter library, filesystem-derived slugs, 3-consumer propagation model enforced.
Preview & Screenshot Governance
β’ [X] T280 [P] [US5] [FR-046] Add T383838preview-staleness job to T383838docs-governance.yml β detects UI composable changes without T383838*Previews.kt updates. Posts advisory PR comment with checklist. Bypassable via T383838skip-preview-check label.
β’ [X] T281 [P] [US5] [FR-047] Add screenshot reference staleness detection to same job β detects T383838*Previews.kt changes without reference image updates in T383838screenshot-tests/src/screenshotTestDebug/reference/. Posts advisory with T383838updateDebugScreenshotTest command.
β’ [X] T282 [US5] Rename workflow T383838Docs Governance β T383838UI & Docs Governance to reflect expanded scope.
β’ [X] T283 [US5] Update T383838docs/developer.md contributing checklist with preview/screenshot maintenance guidance.
β’ [X] T284 [US5] Add dismiss-on-resolve logic: clear preview/screenshot advisory comments when both conditions resolve.
Checkpoint: Unified UI & Docs Governance workflow with advisory checks for docs, previews, and screenshot references.
Phase 12: Chirpy UX & M3 Adaptive Nav Polish
Purpose: Bring Chirpy assistant and docs navigation up to M3 adaptive navigation best practices and improve conversational UX.
M3 Adaptive Navigation
β’ [X] T300 [P] [US2] Integrate T383838ListDetailSceneStrategy metadata into T383838DocsNavigation.kt β T383838listPane() for T383838HelpDocs, T383838detailPane() for T383838HelpDocPage. Enables proper dual-pane layout on tablets/desktop.
β’ [X] T301 [P] [US2] Add T383838feature/docs/build.gradle.kts dependency on T383838libs.jetbrains.compose.material3.adaptive.navigation3.
Global Chirpy State
β’ [X] T310 [P] [US3] Create T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/ai/ChirpySessionHolder.kt β Koin T383838@Single with Compose snapshot state (T383838showSheet, T383838sessionState) for shared Chirpy conversation across panes.
β’ [X] T311 [P] [US3] Refactor T383838DocsNavigation.kt T383838rememberChirpyState() to inject T383838ChirpySessionHolder and derive T383838showFab from backstack β FAB shows on list pane only when no detail is selected, always on detail pane.
β’ [X] T312 [P] [US3] Add auto-intro prompt: Chirpy generates a natural introduction when the sheet first opens with no messages.
Chirpy Bubble Redesign (MessageItem Parity)
β’ [X] T320 [P] [US3] Rewrite T383838ChirpyAssistantSheet.kt bubbles to use T383838Surface + T383838BorderStroke(0.5.dp) + T383838RoundedCornerShape matching T383838MessageItem.kt sender/receiver pattern β user bubbles right-aligned with T383838primaryContainer, Chirpy bubbles left-aligned with T383838surfaceVariant.
β’ [X] T321 [P] [US3] Add 24dp Chirpy avatar (T383838img_chirpy) to the left of every assistant reply bubble.
β’ [X] T322 [P] [US3] Update T383838DocsPreviews.kt with matching bubble styles and avatar.
Thinking State & Source Navigation
β’ [X] T330 [P] [US3] Replace plain "Chirpy is thinking..." text with proper T383838ThinkingBubble composable β assistant-styled bubble with Chirpy avatar and pulsing alpha animation.
β’ [X] T331 [P] [US3] Add T383838SourceRef(id, title) data class to T383838DocModels.kt; update T383838ChirpyMessage.sources to carry page titles alongside IDs.
β’ [X] T332 [P] [US3] Replace plain-text source list with tappable T383838SuggestionChips in T383838AssistantBubble using T383838FlowRow layout and T383838secondaryContainer colors.
β’ [X] T333 [P] [US3] Add T383838onNavigateToPage to T383838ChirpyUiState β dismisses sheet and navigates to referenced doc page. Wire through T383838DocsBrowserScreen and T383838DocsPageRouteScreen.
β’ [X] T334 [US3] Update T383838DocsPreviews.kt with T383838SourceRef sample data, T383838PreviewThinkingBubble, and chip-enabled T383838ChirpyBubble.
Verification
β’ [X] T340 [US3] Verify M3 FAB behavior: confirmed no existing FABs implement hide-on-scroll (consistent with M3 guidelines which do not prescribe it). Chirpy FAB is always-visible, matching all other FABs in the app.
β’ [X] T341 [US3] Build, detekt, spotless, and all T383838feature:docs tests pass. Deployed and verified on Pixel 9 Pro.
Checkpoint: Chirpy assistant follows M3 adaptive nav best practices with global state, MessageItem-style bubbles, thinking animation, and tappable source chips.
Phase 13: Chirpy Messaging UI Polish & Firebase AI Hybrid
β Align Chirpy chat with messaging module conventions; add markdown rendering; update Firebase AI
β binding.
β’ Phase 13 depends on Phase 12 (Chirpy bubble redesign must exist before further polish).
Firebase AI Logic Hybrid API
β’ [X] T350 [P] [US3] Update T383838GeminiNanoDocAssistant.kt to use T383838gemini-2.5-flash-lite model with T383838InferenceMode.PREFER_ON_DEVICE β hybrid on-device/cloud inference via Firebase AI Logic.
β’ [X] T351 [P] [US3] Implement paragraph extraction with markdown stripping and 8K character context budget with 3K retry fallback on token limit errors.
β’ [X] T352 [P] [US3] Migrate imports from deprecated T383838com.google.firebase.ai.ondevice to T383838com.google.firebase.ai.
Markdown Rendering in Assistant Messages
β’ [X] T360 [US3] Replace T383838Text() with mikepenz T383838Markdown() composable in T383838AssistantBubble β Chirpy responses now render rich markdown (headers, lists, bold, code blocks, links).
ChirpyChip Sender Label
β’ [X] T370 [P] [US3] Create T383838ChirpyChip composable in T383838ChirpyAssistantSheet.kt β simplified T383838NodeChip pattern using T383838Card with T383838tertiaryContainer colors, 28dp height, 18dp Chirpy avatar + "Chirpy" text label.
β’ [X] T371 [P] [US3] Replace inline avatar-beside-bubble layout in T383838AssistantBubble and T383838ThinkingBubble with T383838ChirpyChip positioned above the bubble β matching how T383838NodeChip appears above received messages in T383838MessageItem.kt.
MessageInput-Style Text Field
β’ [X] T380 [P] [US3] Replace T383838OutlinedTextField + T383838TextButton("Send") with messaging-style input: T383838RoundedCornerShape(50f) pill shape, T383838IconButton with T383838MeshtasticIcons.Send.
β’ [X] T381 [P] [US3] Add T383838KeyboardOptions(capitalization = Sentences, imeAction = Send) + T383838KeyboardActions(onSend) for keyboard submit support.
β’ [X] T382 [P] [US3] Add T383838LocalSoftwareKeyboardController.current?.hide() on send to dismiss keyboard after submitting a message.
Verification
β’ [X] T390 [US3] Build, detekt, spotless, and all tests pass. Deployed and verified on Pixel 9 Pro.
Checkpoint: Chirpy chat fully aligned with messaging module conventions β NodeChip-style sender label, MessageInput-style text field, markdown rendering, and Firebase AI hybrid inference.
Phase 14: Translation Cascade (Crowdin β ML Kit β English)
Purpose: Enable runtime translation of bundled docs for users whose locale lacks Crowdin coverage.
Translation Service Interface & Implementations
β’ [X] T400 [P] [US1] Create T383838DocTranslationService interface in T383838feature/docs/src/commonMain/kotlin/org/meshtastic/feature/docs/translation/ with T383838translatePage(), T383838isLanguageAvailable(), T383838downloadLanguageModel() and sealed result types.
β’ [X] T401 [P] [US1] Create T383838NoOpDocTranslator for F-Droid/Desktop/iOS that returns T383838Unavailable.
β’ [X] T402 [P] [US1] Create T383838MlKitDocTranslator in T383838androidApp/src/google/kotlin/org/meshtastic/app/translation/ with auto model download, segment-and-translate pattern, and proper T383838suspendCancellableCoroutine bridging.
Markdown-Aware Translation
β’ [X] T410 [P] [US1] Create T383838MarkdownTranslationSegmenter that extracts translatable text from markdown while preserving code blocks, links, images, frontmatter, and HTML blocks.
β’ [X] T411 [P] [US1] Create T383838DocTranslationCache with Okio file-based caching, MD5 content keying, Mutex-guarded concurrency, atomic writes, and access-time eviction at 50MB.
Cascade Integration
β’ [X] T420 [US1] Add T383838hasTranslatedResource() to T383838DocBundleLoader to detect Crowdin-provided locale-qualified bundles.
β’ [X] T421 [US1] Wire cascade into T383838DocsPageScreen: show English content immediately, attempt ML Kit translation in background only when Crowdin bundle is absent, auto-download model on first use.
β’ [X] T422 [US1] Add T383838TranslationSource model enum and UI indicator (subtitle in TopAppBar: "Community translated" or "Auto-translated").
β’ [X] T423 [US1] Add T383838ioDispatcher hop and locale-keyed T383838LaunchedEffect for correct threading and reactivity.
DI & Platform Wiring
β’ [X] T430 [P] [US1] Bind T383838DocTranslationService β T383838MlKitDocTranslator in T383838GoogleAiModule.
β’ [X] T431 [P] [US1] Bind T383838DocTranslationService β T383838NoOpDocTranslator in T383838DesktopKoinModule.
Testing
β’ [X] T440 [P] [US1] Create T383838MarkdownTranslationSegmenterTest (15 tests covering paragraphs, headings, code, links, images, frontmatter, lists, tables, HTML blocks).
β’ [X] T441 [P] [US1] Create T383838DocTranslationCacheTest (8 tests covering cache miss/hit, stale hash, locale isolation, clear, size, eviction, hash consistency).
β’ [X] T442 [P] [US1] Create T383838TranslationCascadeTest (8 tests covering NoOp behavior, fake translator variations, sealed hierarchy).
CI
β’ [X] T450 [US1] Add T383838docs/**/*.md to T383838scheduled-updates.yml T383838add-paths.
Checkpoint: Translation cascade complete β Crowdin bundled translations served automatically by CMP, ML Kit auto-translates on Google flavor when Crowdin unavailable, graceful English fallback on all other platforms.
Phase 15: Web i18n β Crowdin Translations on GitHub Pages
Purpose: Ensure in-repo Crowdin translations flow to web consumers (GH Pages docs site), not just the in-app bundle.
Jekyll Configuration
β’ [X] T500 [P] Add T383838_data/locales.yml with all supported locale metadata (name, text direction).
β’ [X] T501 [P] Add scope defaults in T383838_config.yml for each locale path (T383838es, T383838fr, T383838de, etc.) with T383838layout: locale_page and T383838nav_exclude: true.
β’ [X] T502 [P] Create T383838_layouts/locale_page.html β wraps content with locale banner, language tag, RTL support, and link back to English.
Language Switcher UI
β’ [X] T510 [P] Create T383838_includes/language_switcher.html β detects available translations for current page from T383838site.pages, renders dropdown with locale links.
β’ [X] T511 [P] Add language switcher CSS to T383838_includes/head_custom.html (dropdown, hover states, dark-mode compatible).
β’ [X] T512 [P] Wire language switcher into T383838_includes/header_custom.html alongside theme toggle.
DocsTasks Locale Generation
β’ [X] T520 [P] Extend T383838GenerateDocsBundleTask to discover T383838docs/{locale}/user/ directories and generate locale-qualified HTML + index entries.
β’ [X] T521 [P] Add T383838locales.json manifest output listing all detected translation locales.
β’ [X] T522 [P] Add T383838locale field to index.json entries for locale-aware consumers.
β’ [X] T523 [P] Set T383838lang and T383838dir attributes on generated HTML for locale pages.
Content & Navigation
β’ [X] T530 [P] Create T383838docs/translations.md β lists all available languages with links, Crowdin CTA, contribution instructions.
β’ [X] T531 [P] Crowdin config (T383838crowdin.yml) already maps T383838docs/index.md β T383838docs/{locale}/index.md β locale landing pages auto-generated.
Checkpoint: Crowdin-contributed translations serve to web consumers via Jekyll GH Pages with locale routing, language switcher, and proper locale/RTL HTML attributes. Same markdown source serves both in-app (CMP bundle) and web (Jekyll) consumers.
Served by rngit 1.5.4 - Generated in 0.03s